package com.haohan.cloud.scm.api.goods.trans;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.haohan.cloud.scm.api.constant.NumberPrefixConstant;
import com.haohan.cloud.scm.api.constant.enums.goods.GoodsFromTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.goods.GoodsTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.goods.ModelAttrNameEnum;
import com.haohan.cloud.scm.api.constant.enums.opc.YesNoEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsDTO;
import com.haohan.cloud.scm.api.goods.dto.GoodsExtDTO;
import com.haohan.cloud.scm.api.goods.dto.GoodsInfoDTO;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.entity.*;
import com.haohan.cloud.scm.api.goods.req.manage.EditGoodsReq;
import com.haohan.cloud.scm.api.goods.vo.GoodsModelVO;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import lombok.experimental.UtilityClass;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author cx
 * @date 2019/6/21
 */
@UtilityClass
public class GoodsTrans {

    /**
     * 生成商品信息
     *
     * @param goods
     * @param rule
     * @return
     */
    public static GoodsInfoDTO goodsInfoDTOTrans(Goods goods, GoodsPriceRule rule) {
        GoodsInfoDTO dto = new GoodsInfoDTO();
        dto.setId(Integer.parseInt(goods.getId()));
        dto.setMerId(0);
        dto.setShopId(goods.getShopId());
        dto.setImage(goods.getThumbUrl());
        dto.setStoreName(goods.getGoodsName());
        if (goods.getSimpleDesc() == null) {
            dto.setStoreInfo(goods.getGoodsName());
        } else {
            dto.setStoreInfo(goods.getSimpleDesc());
        }
        dto.setCateId(goods.getGoodsCategoryId());
        dto.setPrice(rule.getMarketPrice());
        if (rule.getVipPrice() == null) {
            dto.setVipPrice(rule.getMarketPrice());
        } else {
            dto.setVipPrice(rule.getVipPrice());
        }
        dto.setOtPrice(rule.getMarketPrice());
        dto.setUnitName(rule.getUnit());
        dto.setSort(Integer.parseInt(goods.getSort()));
        dto.setStock(goods.getStorage().intValue());
        if (rule.getWholesalePrice() == null) {
            dto.setCost(rule.getMarketPrice());
        } else {
            dto.setCost(rule.getWholesalePrice());
        }
        if (goods.getDetailDesc() == null) {
            dto.setDescription(goods.getGoodsName());
        } else {
            dto.setDescription(goods.getDetailDesc());
        }
        if (goods.getSalecFlag() == null) {
            dto.setIsDel(Integer.parseInt(YesNoEnum.no.getType()));
        } else {
            dto.setIsDel(Integer.parseInt(goods.getSalecFlag().getType()));
        }
        // 品牌id 暂未处理
//        if (null != goods.getBrandId()) {
//            dto.setBrand(Integer.parseInt(goods.getBrandId()));
//        }
        return dto;
    }

    public static GoodsModelDTO copyFrom(GoodsModelDTO goodsModelDTO, GoodsModel model, Goods goods) {
        BeanUtil.copyProperties(model, goodsModelDTO);
        goodsModelDTO.setGoodsSn(goods.getGoodsSn());
        goodsModelDTO.setGoodsName(goods.getGoodsName());
        goodsModelDTO.setDetailDesc(goods.getDetailDesc());
        goodsModelDTO.setSimpleDesc(goods.getSimpleDesc());
        goodsModelDTO.setBrandId(goods.getBrandId());
        goodsModelDTO.setGoodsCategoryId(goods.getGoodsCategoryId());
        return goodsModelDTO;
    }

    public static GoodsModelDTO createFromExt(GoodsDTO goodsDTO) {
        GoodsModelDTO goodsModelDTO = goodsDTO.getModelList().get(0);
        goodsModelDTO.setGoodsSn(goodsDTO.getGoodsSn());
        goodsModelDTO.setGoodsName(goodsDTO.getGoodsName());
        goodsModelDTO.setDetailDesc(goodsDTO.getDetailDesc());
        goodsModelDTO.setSimpleDesc(goodsDTO.getSimpleDesc());
        goodsModelDTO.setBrandId("");
        goodsModelDTO.setGoodsCategoryId(goodsDTO.getCategoryId());
        return goodsModelDTO;
    }

    /**
     * 转为 规格属性信息 (种类:普通,重量:500g)
     *
     * @param map
     * @return
     */
    public String transToModelInfo(Map<ModelAttrNameEnum, String> map) {
        List<String> infoList = new ArrayList<>(Math.max(map.size() * 2, 8));
        if (map.size() > 1) {
            // 按枚举大小排序
            Map<ModelAttrNameEnum, String> sortMap = new TreeMap<>(Enum::compareTo);
            map.forEach(sortMap::put);
            sortMap.forEach((key, value) -> infoList.add(key.getDesc().concat(":").concat(value)));
        } else {
            map.forEach((key, value) -> infoList.add(key.getDesc().concat(":").concat(value)));
        }
        return CollUtil.join(infoList, ",");
    }

    /**
     * 根据规格属性信息获取 规格属性 键值对
     * 规格属性格式:  尺码:XL,颜色:蓝
     *
     * @param modelInfo
     * @return 属性名：属性值
     */
    public Map<ModelAttrNameEnum, String> fetchModelInfoMap(String modelInfo) {
        Map<ModelAttrNameEnum, String> map = new HashMap<>(8);
        if (StrUtil.isEmpty(modelInfo)) {
            return map;
        }
        // 全角分隔符替换
        if (modelInfo.contains("，")) {
            modelInfo = modelInfo.replaceAll("，", ",");
        }
        if (modelInfo.contains("：")) {
            modelInfo = modelInfo.replaceAll("：", ":");
        }
        String[] infoArray = modelInfo.split(",");
        for (String s : infoArray) {
            String[] array = s.split(":");
            // 必须是定义的属性名枚举中的
            ModelAttrNameEnum nameEnum = ModelAttrNameEnum.getByDesc(array[0]);
            if (null != nameEnum && !map.containsKey(nameEnum)) {
                map.put(nameEnum, array[1]);
            }
        }
        return map;
    }

    /**
     * 根据规格属性信息获取 规格名称
     * 规格属性格式:  尺码:XL,颜色:蓝
     * 规格名称: XL,蓝
     *
     * @param modelInfo
     * @return
     */
    public String fetchModelName(String modelInfo) {
        Map<ModelAttrNameEnum, String> map = fetchModelInfoMap(modelInfo);
        if (map.isEmpty()) {
            return null;
        }
        return CollUtil.join(map.values(), ",");
    }

    /**
     * 拼接 goodsModelSn
     *
     * @param goodsSn
     * @param num
     * @return
     */
    public static String genGoodsModelSn(String goodsSn, int num) {
        return goodsSn.concat(NumberPrefixConstant.GOODS_MODEL_SN_INFIX).concat(String.valueOf(num));
    }

    /**
     * 转换规格属性名放入map
     *
     * @param modelTotalList
     */
    public static Map<String, List<String>> fetchAttrMap(List<GoodsModelTotal> modelTotalList) {
        // 属性名: 属性值
        Map<String, List<String>> attrMap = new HashMap<>(8);
        modelTotalList.forEach(item -> {
            String attrKey = item.getModelName();
            if (attrMap.containsKey(attrKey)) {
                attrMap.get(attrKey).add(item.getSubModelName());
            } else {
                List<String> set = new ArrayList<>(10);
                set.add(item.getSubModelName());
                attrMap.put(attrKey, set);
            }
        });
        return attrMap;
    }

    public static Map<ModelAttrNameEnum, List<String>> fetchAttrTypeMap(List<GoodsModelTotal> modelTotalList) {
        // 属性名: 属性值
        Map<ModelAttrNameEnum, List<String>> attrMap = new HashMap<>(8);
        modelTotalList.forEach(item -> {
            ModelAttrNameEnum attrKey = ModelAttrNameEnum.getByDesc(item.getModelName());
            if (null == attrKey) {
                throw new ErrorDataException("商品规格类型名称不支持");
            }
            if (attrMap.containsKey(attrKey)) {
                attrMap.get(attrKey).add(item.getSubModelName());
            } else {
                List<String> list = new ArrayList<>(10);
                list.add(item.getSubModelName());
                attrMap.put(attrKey, list);
            }
        });
        return attrMap;
    }

    /**
     * 转换设置 规格 的 类型名称 、modelInfo
     *
     * @param goodsModel
     * @param map        规格名称：规格类型名称
     * @param goodsName
     * @return
     */
    public GoodsModelVO transToVO(GoodsModel goodsModel, Map<String, String> map, String goodsName) {
        GoodsModelVO model = new GoodsModelVO(goodsModel);
        model.setGoodsName(goodsName);
        return modelTypeTrans(model, map);
    }

    /**
     * 转换设置 规格 的 类型名称 、modelInfo
     *
     * @param model modelName 必须
     * @param map   规格名称：规格类型名称
     * @return
     */
    public GoodsModelVO modelTypeTrans(GoodsModelVO model, Map<String, String> map) {
        String[] modelNameArray = StrUtil.split(model.getModelName(), StrUtil.COMMA);
        String[] typeNameArray = new String[modelNameArray.length];
        String[] infoArray = new String[modelNameArray.length];
        String typeName;
        String modelName;
        for (int i = 0, len = modelNameArray.length; i < len; i++) {
            modelName = modelNameArray[i];
            typeName = map.get(modelName);
            if (null == typeName) {
                typeName = "";
            }
            typeNameArray[i] = typeName;
            infoArray[i] = typeName.concat(StrUtil.COLON).concat(modelName);
        }
        model.setTypeName(ArrayUtil.join(typeNameArray, StrUtil.COMMA));
        model.setModelInfo(ArrayUtil.join(infoArray, StrUtil.COMMA));
        return model;
    }

    /**
     * 价格处理, vip 、虚拟价 默认和市场价相同
     *
     * @param priceRule
     */
    public static void priceRuleHandle(GoodsPriceRule priceRule) {
        if (null == priceRule.getVipPrice()) {
            priceRule.setVipPrice(priceRule.getMarketPrice());
        }
        if (null == priceRule.getVirtualPrice()) {
            priceRule.setVirtualPrice(priceRule.getMarketPrice());
        }
    }

    /**
     * 价格处理, vip 、虚拟价 默认和市场价相同
     *
     * @param goods
     */
    public static void priceRuleHandle(GoodsExtDTO goods) {
        if (null == goods.getVipPrice()) {
            goods.setVipPrice(goods.getMarketPrice());
        }
        if (null == goods.getVirtualPrice()) {
            goods.setVirtualPrice(goods.getMarketPrice());
        }
    }

    /**
     * 新增时设置商品的状态、标记
     *
     * @param goods
     */
    public static void goodsInitDefault(Goods goods) {
        goods.setId(null);
        if (null == goods.getSaleRule()) {
            goods.setSaleRule(YesNoEnum.no);
        }
        if (null == goods.getServiceSelection()) {
            goods.setServiceSelection(YesNoEnum.no);
        }
        if (null == goods.getDeliveryRule()) {
            goods.setDeliveryRule(YesNoEnum.no);
        }
        if (null == goods.getGoodsGift()) {
            goods.setGoodsGift(YesNoEnum.no);
        }
        if (null == goods.getGoodsModel()) {
            goods.setGoodsModel(YesNoEnum.no);
        }
        if (null == goods.getGoodsFrom()) {
            goods.setGoodsFrom(GoodsFromTypeEnum.platform);
        }
        if (null == goods.getGoodsType()) {
            goods.setGoodsType(GoodsTypeEnum.physical);
        }
        if (null == goods.getSalecFlag()) {
            goods.setSalecFlag(YesNoEnum.no);
        }
        if (null == goods.getStorage()) {
            goods.setStorage(new BigDecimal(1000));
        }
        if (null == goods.getSort()) {
            goods.setSort("100");
        }
    }

    public static GoodsPriceRule initGoodsPriceRule(Goods goods, EditGoodsReq req) {
        GoodsPriceRule priceRule = new GoodsPriceRule();
        priceRule.setRuleName("定价");
        priceRule.setShopId(goods.getShopId());
        priceRule.setMerchantId(goods.getMerchantId());
        priceRule.setGoodsId(goods.getId());
        priceRule.setMarketPrice(req.getMarketPrice());
        priceRule.setVipPrice(null == req.getVipPrice() ? req.getMarketPrice() : req.getVipPrice());
        priceRule.setVirtualPrice(null == req.getVirtualPrice() ? req.getMarketPrice() : req.getVirtualPrice());
        priceRule.setUnit(req.getUnit());
        priceRule.setStatus(1);
        return priceRule;
    }

    /**
     * 规格新增、修改时初始化设置
     *
     * @param model
     */
    public static void modelInitDefault(GoodsModel model) {
        if (null == model.getVirtualPrice()) {
            model.setVirtualPrice(model.getModelPrice());
        }
        if (null == model.getCostPrice()) {
            model.setCostPrice(model.getModelPrice());
        }
        if (null == model.getModelStorage()) {
            model.setModelStorage(new BigDecimal(1000));
        }
        if (null == model.getStocksForewarn()) {
            model.setStocksForewarn(model.getModelStorage().intValue());
        }
    }

    /**
     * 商品规格 平台定价设置
     *
     * @param platformPrice
     * @param model
     */
    public static void modelPlatformPrice(PlatformGoodsPrice platformPrice, GoodsModelVO model) {
        if (null != platformPrice) {
            // 原规格价格设为虚拟价，平台定价设为当前规格价
            model.setVirtualPrice(model.getModelPrice());
            model.setModelPrice(platformPrice.getPrice());
        }
    }

    /**
     * 商品规格 平台定价设置
     *
     * @param platformPrice
     * @param model
     */
    public static void modelPlatformPrice(PlatformGoodsPrice platformPrice, GoodsModelDTO model) {
        if (null != platformPrice) {
            // 原规格价格设为虚拟价，平台定价设为当前规格价
            model.setVirtualPrice(model.getModelPrice());
            model.setModelPrice(platformPrice.getPrice());
        }
    }

    public static GoodsModelVO transToVO(GoodsModelDTO model) {
        // 缺少typeName
        GoodsModelVO modelVO = new GoodsModelVO();
        modelVO.setModelId(model.getId());
        modelVO.setGoodsModelSn(model.getGoodsModelSn());
        modelVO.setGoodsId(model.getGoodsId());
//        modelVO.setTypeName();
        modelVO.setModelName(model.getModelName());
        modelVO.setGoodsName(model.getGoodsName());
        modelVO.setModelUrl(model.getModelUrl());
        modelVO.setModelInfo(model.getModelInfo());
        modelVO.setModelCode(model.getModelCode());
        modelVO.setModel(model.getModel());
        modelVO.setModelPrice(model.getModelPrice());
        modelVO.setVirtualPrice(model.getVirtualPrice());
        modelVO.setCostPrice(model.getCostPrice());
        modelVO.setModelUnit(model.getModelUnit());
        modelVO.setModelStorage(model.getModelStorage());
        modelVO.setWeight(model.getWeight());
        modelVO.setVolume(model.getVolume());
        modelVO.setStocksForewarn(model.getStocksForewarn());
        return modelVO;
    }
}
